﻿using System;
using System.Windows.Forms;
using DevComponents.DotNetBar.Rendering;
using DevComponents.DotNetBar;
using System.Drawing;
using mshtml;
using System.Runtime.InteropServices;
using System.IO;
using MSDN.Html.Editor;
using DevComponents.Editors;
using System.Collections.Generic;
using System.ComponentModel;
using Pavonis.COM.IOleCommandTarget;
using Pavonis.COM;

namespace NotesBook
{
    public partial class FormMain : Office2007RibbonForm, IMessageFilter
    {
        #region 属性

        private int nodeID { get; set; }

        private string ImgSavePath
        {
            get
            {
                string s = string.Format(@"{0}/images/{1}/", Application.StartupPath.Replace('\\', '/'), nodeID);
                if (!Directory.Exists(s))
                    Directory.CreateDirectory(s);
                return s;
            }
        }
        private string FileSavePath
        {
            get
            {
                string s = string.Format(@"{0}/files/{1}/", Application.StartupPath.Replace('\\', '/'), nodeID);
                if (!Directory.Exists(s))
                    Directory.CreateDirectory(s);
                return s;
            }
        }

        private bool _MColorSelected;
        private eOffice2007ColorScheme _MBaseColorScheme = eOffice2007ColorScheme.Blue;

        #endregion

        public FormMain()
        {
            InitializeComponent();
            Application.AddMessageFilter(this);
            nodeID = 1;
        }

        #region 事件处理函数

        #region 退出程序
        private void buttonExit_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void FormMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            string imgSavePath = Application.StartupPath.Replace('\\', '/') + "/images/";
            string fileSavePath = Application.StartupPath.Replace('\\', '/') + "/files/";
            DirectoryInfo di = new DirectoryInfo(imgSavePath);
            if (di.Exists)
                di.Delete(true);
            di = new DirectoryInfo(fileSavePath);
            if (di.Exists)
                di.Delete(true);
        }
        #endregion

        #region 更换主题
        private void btnOffice2007Blue_Click(object sender, EventArgs e)
        {
            styleManager1.ManagerStyle = eStyle.Office2007Blue;
        }
        private void btnOffice2007Silver_Click(object sender, EventArgs e)
        {
            styleManager1.ManagerStyle = eStyle.Office2007Silver;
        }
        private void btnOffice2007Black_Click(object sender, EventArgs e)
        {
            styleManager1.ManagerStyle = eStyle.Office2007Black;
        }
        private void btnOffice2007VistaGlass_Click(object sender, EventArgs e)
        {
            styleManager1.ManagerStyle = eStyle.Office2007VistaGlass;
        }
        private void btnOffice2010Blue_Click(object sender, EventArgs e)
        {
            styleManager1.ManagerStyle = eStyle.Office2010Blue;
        }
        private void btnOffice2010Silver_Click(object sender, EventArgs e)
        {
            styleManager1.ManagerStyle = eStyle.Office2010Silver;
        }
        private void btnOffice2010Black_Click(object sender, EventArgs e)
        {
            styleManager1.ManagerStyle = eStyle.Office2010Black;
        }
        private void btnOffice2013_Click(object sender, EventArgs e)
        {
            styleManager1.ManagerStyle = eStyle.Office2013;
        }
        private void btnVisualStudio2010Blue_Click(object sender, EventArgs e)
        {
            styleManager1.ManagerStyle = eStyle.VisualStudio2010Blue;
        }
        private void btnWindows7Blue_Click(object sender, EventArgs e)
        {
            styleManager1.ManagerStyle = eStyle.Windows7Blue;
        }
        private void btnMetro_Click(object sender, EventArgs e)
        {
            styleManager1.ManagerStyle = eStyle.Metro;
        }
        private void colorPickerDropDown1_SelectedColorChanged(object sender, EventArgs e)
        {
            _MColorSelected = true;
            RibbonPredefinedColorSchemes.ChangeOffice2007ColorTable(_MBaseColorScheme, colorPickerDropDown1.SelectedColor);
        }
        private void colorPickerDropDown1_ColorPreview(object sender, ColorPreviewEventArgs e)
        {
            RibbonPredefinedColorSchemes.ChangeOffice2007ColorTable(_MBaseColorScheme, e.Color);
        }
        private void colorPickerDropDown1_ExpandChange(object sender, EventArgs e)
        {
            if (colorPickerDropDown1.Expanded)
            {
                _MColorSelected = false;
                _MBaseColorScheme = ((Office2007Renderer)GlobalManager.Renderer).ColorTable.InitialColorScheme;
            }
            else
            {
                if (_MColorSelected == false)
                    RibbonPredefinedColorSchemes.ChangeOffice2007ColorTable(_MBaseColorScheme);
            }
        }
        #endregion

        #region 更换文件按钮图标
        private void btnOffice0_Click(object sender, EventArgs e)
        {
            applicationButton1.Image = Properties.Resources.Image0;
            applicationButton1.HoverImage = Properties.Resources.Image0;
            applicationButton1.PressedImage = Properties.Resources.Image0;
        }

        private void btnOffice1_Click(object sender, EventArgs e)
        {
            applicationButton1.Image = Properties.Resources.Image1;
            applicationButton1.HoverImage = Properties.Resources.Image1;
            applicationButton1.PressedImage = Properties.Resources.Image1;
        }

        private void btnOffice2_Click(object sender, EventArgs e)
        {
            applicationButton1.Image = Properties.Resources.Image2;
            applicationButton1.HoverImage = Properties.Resources.Image2;
            applicationButton1.PressedImage = Properties.Resources.Image2;
        }

        private void btnWindows7_Click(object sender, EventArgs e)
        {
            applicationButton1.Image = Properties.Resources.Image;
            applicationButton1.HoverImage = Properties.Resources.HoverImage;
            applicationButton1.PressedImage = Properties.Resources.PressedImage;
        }

        private void btnWindows_Click(object sender, EventArgs e)
        {
            applicationButton1.Image = Properties.Resources.Image3;
            applicationButton1.HoverImage = Properties.Resources.HoverImage3;
            applicationButton1.PressedImage = Properties.Resources.PressedImage3;
        }

        private void btnSmiley_Click(object sender, EventArgs e)
        {
            applicationButton1.Image = Properties.Resources.Image4;
            applicationButton1.HoverImage = Properties.Resources.HoverImage4;
            applicationButton1.PressedImage = Properties.Resources.PressedImage4;
        }
        #endregion

        #region 快速插入表格
        private void fastInsertTable1_CancelSelect(object sender, EventArgs e)
        {
            lblTableSize.Text = "插入表格";
        }

        private void fastInsertTable1_SelectComplete(object sender, FastInsertTableControl.FastInsertTableEvents.SelectCompleteEventArgs e)
        {
            btnTable.ClosePopup();
            HtmlTableProperty tableProperties = new HtmlTableProperty(true);
            tableProperties.TableColumns = (byte)(e.Cols);
            tableProperties.TableRows = (byte)(e.Rows);
            htmlEditor.TableInsert(tableProperties);
        }

        private void fastInsertTable1_Selecting(object sender, FastInsertTableControl.FastInsertTableEvents.SelectingEventArgs e)
        {
            lblTableSize.Text = string.Format("{0}×{1}表格", e.Rows, e.Cols);
        }
        #endregion

        #region 异步下载图片

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            Dictionary<string, string> dicUrls = e.Argument as Dictionary<string, string>;
            BackgroundWorker bw = sender as BackgroundWorker;
            this.Invoke(new MethodInvoker(delegate()
            {
                progressBar1.Visible = true;
                labelStatus.Text = "正在下载图片, 按ESC键取消";
            }));
            foreach (KeyValuePair<string, string> item in dicUrls)
            {
                if (bw.CancellationPending)
                {
                    e.Cancel = true;
                    break;
                }
                else
                {
                    Helper.DownLoadFile(item.Value, item.Key, bw);
                    htmlEditor.Invoke(new MethodInvoker(delegate()
                    {
                        htmlEditor.BodyHtml = htmlEditor.BodyHtml;
                    }));
                }
            }
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar1.Value = e.ProgressPercentage;
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                MessageBox.Show(this, e.Error.Message, "错误");
            }
            else if (e.Cancelled)
            {
                labelStatus.Text = "下载已取消";
            }
            else
            {
                labelStatus.Text = "图片下载完成";
            }
            Helper.SetTimeout(300, delegate()
            {
                this.Invoke(new MethodInvoker(delegate()
                {
                    labelStatus.Text = "";
                }));
            });
            progressBar1.Visible = false;
        }

        #endregion

        private void cbFont_ExpandChange(object sender, EventArgs e)
        {
            htmlEditor.FormatFontName(((ComboItem)cbFont.SelectedItem).Text);
        }

        private void cbFontSize_ExpandChange(object sender, EventArgs e)
        {
            htmlEditor.FormatFontSize((HtmlFontSize)(cbFontSize.SelectedIndex + 1));
        }

        private void ribbonBar2_LaunchDialog(object sender, EventArgs e)
        {
            htmlEditor.FormatFontAttributesPrompt();
        }

        private void btn_Click(object sender, EventArgs e)
        {
            ButtonItem btn = ((ButtonItem)sender);
            if (btn.Tag != null)
                htmlEditor.ProcessCommand(btn.Tag.ToString());
        }
        //缩放
        private void zoomSlider_ValueChanged(object sender, EventArgs e)
        {
            int factor = 100;
            if (zoomSlider.Value <= 1000)
            {
                factor = (int)(((float)zoomSlider.Value / (float)100) * 9) + 10;
            }
            else if (zoomSlider.Value <= 1000)
                factor = 100;
            else
            {
                factor = (int)(((float)zoomSlider.Value / (float)5) * 2) - 300;
            }
            htmlEditor.Zoom(factor);
            zoomSlider.Text = string.Format("{0}%", factor);
        }

        private void htmlEditor_OverWriteToggled(object sender, OverWriteToggledEventArgs e)
        {
            btnToggleOverwrite.Text = (e.InsertMode == InsertMode.Insert) ? "插入" : "改写";
        }

        private void htmlEditor_ContextMenuShowing(object sender, IHTMLEventObj e)
        {
            IHTMLElement el = e.srcElement;
            bool isAttach = (el is HTMLImgClass) && ((HTMLImgClass)el).getAttributeNode("attach") != null;
            bool isImage = (el is HTMLImgClass) && ((HTMLImgClass)el).getAttributeNode("attach") == null;
            bool isTable = (el is HTMLTableCellClass) || (el is HTMLTableRowClass) || (el is HTMLTableClass);

            this.cmTableProperties.Visible = isTable;
            this.cmTableInsertRow.Visible = isTable;
            this.cmTableDeleteRow.Visible = isTable;
            this.cmAttachSaveTo.Visible = isAttach;
            this.cmImageSaveTo.Visible = isImage;
            cm1.Popup(Cursor.Position.X, Cursor.Position.Y);
        }

        private void htmlEditor_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            btnBold.Checked = e.FontProperty.Bold;
            btnItalic.Checked = e.FontProperty.Italic;
            btnStrikeout.Checked = e.FontProperty.Strikeout;
            btnSubscript.Checked = e.FontProperty.Subscript;
            btnSuperscript.Checked = e.FontProperty.Superscript;
            btnUnderline.Checked = e.FontProperty.Underline;
            cbFontSize.SelectedIndex = (int)e.FontProperty.Size - 1;

            btnFormattedNormal.Checked = false;
            btnFormattedHeading1.Checked = false;
            btnFormattedHeading2.Checked = false;
            btnFormattedHeading3.Checked = false;
            btnFormattedHeading4.Checked = false;
            btnFormattedHeading5.Checked = false;
            btnFormattedHeading6.Checked = false;
            switch (e.FormatBlockStyle)
            {
                case "普通": btnFormattedNormal.Checked = true; break;
                case "标题 1": btnFormattedHeading1.Checked = true; break;
                case "标题 2": btnFormattedHeading2.Checked = true; break;
                case "标题 3": btnFormattedHeading3.Checked = true; break;
                case "标题 4": btnFormattedHeading4.Checked = true; break;
                case "标题 5": btnFormattedHeading5.Checked = true; break;
                case "标题 6": btnFormattedHeading6.Checked = true; break;
            }
            foreach (ComboItem item in cbFont.Items)
            {
                if (item.Text == e.FontProperty.Name)
                {
                    cbFont.SelectedItem = item;
                    return;
                }
            }
        }

        private void htmlEditor_ControlSelect(object sender, IHTMLEventObj e)
        {
            if (e.srcElement != null)
            {
                if (e.srcElement is HTMLImgClass)
                {

                }
            }
        }

        private void htmlEditor_OnPaste(object sender, OnPasteEventArgs e)
        {
            if (!backgroundWorker1.IsBusy)
            {
                if (ClipboardHelper.IsBitmap)
                {
                    Bitmap b = ClipboardHelper.Bitmap;
                    htmlEditor.SelectedHtml = HtmlHelper.Bitmap2Html(b, ImgSavePath);
                }
                else if (ClipboardHelper.IsRtf)
                {
                    string rtfString = ClipboardHelper.Rtf;
                    htmlEditor.SelectedHtml = HtmlHelper.Rtf2Html(rtfString, ImgSavePath);
                }
                else if (ClipboardHelper.IsHtml)
                {
                    string htmlString = ClipboardHelper.Html;
                    htmlEditor.SelectedHtml = HtmlHelper.Web2Html(htmlString, ImgSavePath, backgroundWorker1);
                }
                else if (ClipboardHelper.IsFileDrop)
                {
                    string[] files = ClipboardHelper.FileDrop;
                    htmlEditor.SelectedHtml = HtmlHelper.Attach2Html(files, ImgSavePath, FileSavePath, delegate(InsertAttachArgs args)
                    {

                    });
                }
                else
                    htmlEditor.TextPaste();
            }
            e.Cancel = true;
        }

        #endregion

        #region IMessageFilter

        private int WM_KEYDOWN = 0x0100;

        [DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
        private static extern IntPtr GetParent(IntPtr hWnd);

        [DllImport("User32.dll", EntryPoint = "PostMessage")]
        private static extern int PostMessage(
            int hWnd,   //   handle   to   destination   window   
            int Msg,   //   message   
            int wParam,   //   first   message   parameter   
            int lParam   //   second   message   parameter   
        );

        public bool PreFilterMessage(ref Message msg)
        {
            if (msg.Msg == WM_KEYDOWN)
            {
                if (Control.ModifierKeys == Keys.None && ((Keys)msg.WParam.ToInt32() & Keys.KeyCode) == Keys.Escape && backgroundWorker1.IsBusy)
                {
                    backgroundWorker1.CancelAsync();
                }
            }
            return false;
        }

        #endregion
    }
}
